import pandas as pd
import numpy as np


def calculate_trading_indicators(klines_data):
    """
    计算交易指标，包括Q值、操盘线和空头线
    
    参数:
        klines_data: 包含开盘价、最高价、最低价、收盘价的字典或DataFrame
                    必须包含以下键或列: 'open', 'high', 'low', 'close'
    
    返回:
        tuple: (trading_line, short_line)
            trading_line: 操盘线
            short_line: 空头线
    """
    try:
        # 确保数据格式正确
        if isinstance(klines_data, dict):
            close = klines_data['close']
            open_price = klines_data['open']
            high = klines_data['high']
            low = klines_data['low']
        elif hasattr(klines_data, 'close'):
            close = klines_data.close
            open_price = klines_data.open
            high = klines_data.high
            low = klines_data.low
        else:
            raise ValueError("klines_data 格式不正确，需要包含 open, high, low, close 字段")
        
        # 计算Q值
        Q = (3 * close + low + open_price + high) / 6
        Q = pd.Series(Q)
        
        # 手动实现 REF 函数
        def ref(series, n=1):
            return series.shift(n)
        
        # 计算操盘线（26期Q值加权平均）
        terms = [
            26 * Q,
            25 * ref(Q, 1),
            24 * ref(Q, 2),
            23 * ref(Q, 3),
            22 * ref(Q, 4),
            21 * ref(Q, 5),
            20 * ref(Q, 6),
            19 * ref(Q, 7),
            18 * ref(Q, 8),
            17 * ref(Q, 9),
            16 * ref(Q, 10),
            15 * ref(Q, 11),
            14 * ref(Q, 12),
            13 * ref(Q, 13),
            12 * ref(Q, 14),
            11 * ref(Q, 15),
            10 * ref(Q, 16),
            9 * ref(Q, 17),
            8 * ref(Q, 18),
            7 * ref(Q, 19),
            6 * ref(Q, 20),
            5 * ref(Q, 21),
            4 * ref(Q, 22),
            3 * ref(Q, 23),
            2 * ref(Q, 24),
            ref(Q, 25)
        ]
        trading_line = pd.Series(sum(terms) / 351)
        
        # 手动实现 EMA 函数
        def ema(series, n=10):
            return series.ewm(span=n, adjust=False).mean()
        
        # 计算空头线（操盘线的7期EMA）
        short_line = ema(trading_line, 7)
        
        return trading_line, short_line
        
    except Exception as e:
        # 捕获并记录异常
        import logging
        logging.error(f"计算交易指标时出错: {e}")
        raise


def check_crossover_signals(trading_line, short_line):
    """
    检查金叉和死叉信号
    
    参数:
        trading_line: 操盘线
        short_line: 空头线
    
    返回:
        dict: 包含信号信息的字典
            {'golden_cross': bool, 'death_cross': bool}
                golden_cross: 是否出现金叉信号
                death_cross: 是否出现死叉信号
    """
    signals = {
        'golden_cross': False,
        'death_cross': False
    }
    
    # 确保数据长度足够
    if len(trading_line) >= 3 and len(short_line) >= 3:
        # 检查金叉（操盘线从下向上穿过空头线）
        signals['golden_cross'] = trading_line.iloc[-2] > short_line.iloc[-2] and trading_line.iloc[-3] < short_line.iloc[-3]
        
        # 检查死叉（操盘线从上向下穿过空头线）
        signals['death_cross'] = trading_line.iloc[-2] < short_line.iloc[-2] and trading_line.iloc[-3] > short_line.iloc[-3]
    
    return signals


def check_trend_direction(trading_line, short_line):
    """
    检查当前趋势方向
    
    参数:
        trading_line: 操盘线
        short_line: 空头线
    
    返回:
        str: 趋势方向
            'bullish': 多头趋势
            'bearish': 空头趋势
            'neutral': 中性
    """
    if len(trading_line) >= 2 and len(short_line) >= 2:
        if trading_line.iloc[-2] > short_line.iloc[-2]:
            return 'bullish'  # 多头趋势
        elif trading_line.iloc[-2] < short_line.iloc[-2]:
            return 'bearish'  # 空头趋势
    return 'neutral'  # 中性或数据不足